package org.techism.server.dao.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.techism.client.bo.Group;
import org.techism.client.bo.GroupAttributes;
import org.techism.server.dao.GroupDao;

import com.google.appengine.api.datastore.DatastoreService;
import com.google.appengine.api.datastore.DatastoreServiceFactory;
import com.google.appengine.api.datastore.Entity;
import com.google.appengine.api.datastore.EntityNotFoundException;
import com.google.appengine.api.datastore.Link;
import com.google.appengine.api.datastore.Query;
import com.google.appengine.api.datastore.Query.FilterOperator;

public class GroupDaoImpl implements GroupDao {

	private static final Logger log = Logger.getLogger(GroupDaoImpl.class
			.getName());

	private DatastoreService datastoreService = DatastoreServiceFactory
			.getDatastoreService();

	@Override
	public SortedMap<String, Integer> findAllTags() {
		final Query query = new Query("Group");
		final SortedMap<String, Integer> result = new TreeMap<String, Integer>();
		for (final Entity taskEntity : datastoreService.prepare(query)
				.asIterable()) {
			try {
				final Entity entity = datastoreService.get(taskEntity.getKey());
				final List<String> tags = (List<String>) entity
						.getProperty(GroupAttributes.TAGS.toString());
				if (tags != null) {
					for (final String tag : tags) {
						if (result.get(tag) == null) {
							result.put(tag, 1);
						} else {
							result.put(tag, result.get(tag) + 1);
						}
					}
				}
			} catch (final EntityNotFoundException ex) {
				log.log(Level.WARNING, ex.getMessage(), ex);
			}
		}
		return result;
	}

	@Override
	public List<Group> findAllGroups() {
		final Query query = new Query("Group");
		query.addSort(GroupAttributes.NAME.toString());
		final List<Group> groups = new ArrayList<Group>();
		for (final Entity taskEntity : datastoreService.prepare(query)
				.asIterable()) {
			try {
				final Entity entity = datastoreService.get(taskEntity.getKey());
				final Group group = getGroup(entity);
				groups.add(group);
			} catch (final EntityNotFoundException ex) {
				log.log(Level.WARNING, ex.getMessage(), ex);
			}
		}
		return groups;
	}

	@Override
	public List<Group> findGroupsByTag(final String tag) {
		final Query query = new Query("Group");
		query.addSort(GroupAttributes.NAME.toString());
		query.addFilter(GroupAttributes.TAGS.toString(), FilterOperator.EQUAL,
				tag);
		final List<Group> groups = new ArrayList<Group>();
		for (final Entity taskEntity : datastoreService.prepare(query)
				.asIterable()) {
			try {
				final Entity entity = datastoreService.get(taskEntity.getKey());
				final Group group = getGroup(entity);
				groups.add(group);
			} catch (final EntityNotFoundException ex) {
				log.log(Level.WARNING, ex.getMessage(), ex);
			}
		}
		return groups;
	}

	private Group getGroup(final Entity entity) {
		final Group group = new Group();
		final String name = (String) entity.getProperty(GroupAttributes.NAME
				.toString());
		group.setName(name);
		final Link url = (Link) entity.getProperty(GroupAttributes.URL
				.toString());
		if (url != null) {
			group.setUrl(url.getValue());
		}
		final List<String> tags = (List<String>) entity
				.getProperty(GroupAttributes.TAGS.toString());
		group.setTags(tags);
		return group;
	}
}